﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Drawing;

using DotSpatial.Topology;

using System.Windows.Forms;

using Point=System.Drawing.Point;

using System.Drawing.Drawing2D;


namespace FXnaGis
{

   

    /// <summary>
    /// 为拓扑类图层加入对应的逻辑算法
    /// </summary>
    public class FTopologyEditMF:FMapFunction
    {

        public FTopologyEditMF(FMapFrame frame)
            : base(frame)
        {

            frame.LayerService.SelectedLayerChanged += new EventHandler(frame_SelectedLayerChanged);

 

        }


        #region 对外事件


       

        public event EventHandler AskAddGeometry;


        #endregion

        void frame_SelectedLayerChanged(object sender, EventArgs e)
        {
            if (this._geoMapFrame.LayerService.SelectedLayer!=null)
            {
                FTopologyLayer layer = this._geoMapFrame.LayerService.SelectedLayer as FTopologyLayer;
                if (layer!=null)
                {
                    this._currentLayer = layer;

                    return;
                    
                }
                
            }



            //当不满足上述的条件时,设置为空值以防止部分操作

            this._currentLayer = null;


           


        }


        FTopologyEditMode _mode = FTopologyEditMode.POINT;

        public FTopologyEditMode Mode
        {
            get { return _mode; }
            set {
                
                _mode = value; 
            
            }
        }




        private List<Coordinate> _coordinates = new List<Coordinate>();

        /// <summary>
        /// 这里我们把他设计为对外的数据暂存接口
        /// 外部通过它来获得具体的坐标值
        /// </summary>
        public List<Coordinate> Coordinates
        {
            get { return _coordinates; }
           

        }


        //这里由于是地理信息绘制，可能在绘制过程中存在缩放等问题，所以实际坐标会变化，不能存储屏幕坐标为依据

        List<Coordinate> _coordsInner = new List<Coordinate>();


        List<Point> _pts = new List<Point>();



        private Point _mousePosition;



        //需要明确当前图层的概念以及取得方式


        FTopologyLayer _currentLayer;

        public FTopologyLayer CurrentLayer
        {
            get { return _currentLayer; }
            
        }




        protected override void OnActivate()
        {
            base.OnActivate();

            this._coordsInner.Clear();
            this._coordinates.Clear();


        }

        protected override void OnDeactivate()
        {
            base.OnDeactivate();
        }


        protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
        {

            

            switch (this._mode)
            {
                case FTopologyEditMode.POINT:



                    break;
                case FTopologyEditMode.LINE:
                    break;
                case FTopologyEditMode.LINEVERTEX:
                    break;
                default:
                    break;
            }

            base.OnMouseDown(e);
        }


        protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (this._mode==FTopologyEditMode.LINE)
            {
                //需要绘制点
                if (this._coordsInner.Count>0)
                {

                    this._mousePosition = e.Location;


                    this._geoMapFrame.Parent.Invalidate();


                    
                }
                
            }


        }


        protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
        {


            if (e.Button==MouseButtons.Left)
            {

                Coordinate c = this._geoMapFrame.BufferToProj(e.Location);;

                switch (this._mode)
                {
                       

                    case FTopologyEditMode.POINT:

                        this._coordinates.Clear();
                       

                        this._coordinates.Add(c);

                        this.AddGeomotry();


                       




                        break;
                    case FTopologyEditMode.LINE:




                        //这里需要加入判断逻辑，

                        this._coordsInner.Add(c);

                        DotSpatial.Topology.Point p = new DotSpatial.Topology.Point(c);

                        //目前的点时候与一个线段相交，如果相交，且这个点不是第一个点，则立即结束绘制，并返回图形

                        //看来这里不能取实际的范围，最好是取像素值，但是像素值又很难算出线条的相交情况，纠结了

                        if (this._coordsInner.Count>=2)
                        {

                            foreach (FShape item in this._currentLayer.TempVisibleShapes)
                            {
                                FLineShape line = item as FLineShape;
                                if (line!=null)
                                {


                                    //目前的算法是不成功的，之后再改进吧，先做别的
                                  

                                    //if (line.Line.Intersects(p))
                                    //{

                                    //    this.FinishLine();

                                    //}
                                    
                                }
                                
                            }

                            if (true)
                            {
                                
                            }
                            
                        }


                       
                        



                      

                        break;
                    case FTopologyEditMode.LINEVERTEX:

                        this._coordinates.Clear();
                        


                        this._coordinates.Add(c);


                        this.AddGeomotry();


                        break;
                    default:
                        break;
                }


                
            }

            if (e.Button==MouseButtons.Right)
            {

                if (this._mode==FTopologyEditMode.LINE)
                {


                    this.FinishLine();
                    
                }


                
            }


            


            this._geoMapFrame.Parent.Invalidate();

           
            base.OnMouseUp(e);

        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);



            if (e.KeyCode==Keys.Escape)
            {

                this._coordsInner.Clear();

                this._coordinates.Clear();

                this._geoMapFrame.Parent.Invalidate();




            }



        }


        protected override void OnDraw(FMapDrawArgs e)
        {
            if (this._mode==FTopologyEditMode.LINE)
            {



                //更换坐标与存储

                this._pts.Clear();


                if (this._coordsInner.Count>0)
                {

                    



                    foreach (Coordinate c in this._coordsInner)
                    {
                        this._pts.Add(this._geoMapFrame.ProjToBuffer(c));
                        
                    }

                    
                }

                if (this._pts.Count > 0)
                {
                    //GraphicsPath gp = new GraphicsPath();
                    //gp.AddLines (this._pts.ToArray ());

                    //e.Graphics.DrawPath(Pens.DodgerBlue, gp);



                    //先绘制固定线条

                    if (this._pts.Count>1)
                    {
                        e.Graphics.DrawLines(Pens.DodgerBlue,this._pts.ToArray ());
                        
                    }

                    //然后绘制活动线条



                    e.Graphics.DrawLine(Pens.DodgerBlue, this._pts[this._pts.Count -1], this._mousePosition);



                  




                   

                }

                
            }

           




            base.OnDraw(e);





        }



        protected void FinishLine()
        {

            this._coordinates.Clear();


            this._coordinates.AddRange(this._coordsInner);



            this._coordsInner.Clear();







            this.AddGeomotry();


        }


        protected void AddGeomotry()
        {


            if (this.AskAddGeometry != null)
            {
                this.AskAddGeometry(this, EventArgs.Empty);

            }



        }






    }
}
